/**
 * 习题集系统类 - 构造版本2.0
 * 
 * 设计特点：
 * 1. 管理多个Exercise对象
 * 2. 提供批量操作和筛选功能
 * 3. 支持自动生成练习集
 * 4. 包含完整的统计信息
 * 5. 支持习题集的序列化
 * 
 * 业务规则：
 * - 习题ID唯一
 * - 支持按不同条件筛选
 * - 提供学习进度分析
 * - 支持导出和导入功能
 */
package edu.scut.oop.exercise.v2;

import java.util.*;
import java.util.stream.Collectors;

public class ExerciseSet {
    
    // 成员变量
    private String setName;                    // 习题集名称
    private int setId;                         // 习题集ID
    private List<Exercise> exercises;          // 习题列表
    private int nextExerciseId;                // 下一个习题ID
    private long createTime;                   // 创建时间
    private String description;                // 描述信息
    
    /**
     * 构造函数
     * @param setName 习题集名称
     * @param setId 习题集ID
     */
    public ExerciseSet(String setName, int setId) {
        this.setName = setName;
        this.setId = setId;
        this.exercises = new ArrayList<>();
        this.nextExerciseId = 1;
        this.createTime = System.currentTimeMillis();
        this.description = "";
    }
    
    /**
     * 构造函数（包含描述）
     * @param setName 习题集名称
     * @param setId 习题集ID
     * @param description 描述信息
     */
    public ExerciseSet(String setName, int setId, String description) {
        this(setName, setId);
        this.description = description;
    }
    
    /**
     * 添加习题
     * @param exercise 习题对象
     * @return 是否添加成功
     */
    public boolean addExercise(Exercise exercise) {
        if (exercise == null) {
            return false;
        }
        
        // 检查ID是否冲突
        for (Exercise existing : exercises) {
            if (existing.getExerciseId() == exercise.getExerciseId()) {
                return false; // ID重复
            }
        }
        
        exercises.add(exercise);
        return true;
    }
    
    /**
     * 移除习题
     * @param exerciseId 习题ID
     * @return 是否移除成功
     */
    public boolean removeExercise(int exerciseId) {
        return exercises.removeIf(exercise -> exercise.getExerciseId() == exerciseId);
    }
    
    /**
     * 查找习题
     * @param exerciseId 习题ID
     * @return 习题对象，如果不存在则返回null
     */
    public Exercise findExercise(int exerciseId) {
        return exercises.stream()
                .filter(exercise -> exercise.getExerciseId() == exerciseId)
                .findFirst()
                .orElse(null);
    }
    
    /**
     * 根据难度筛选习题
     * @param difficulty 难度级别
     * @return 符合条件的习题列表
     */
    public List<Exercise> getExercisesByDifficulty(Exercise.Difficulty difficulty) {
        return exercises.stream()
                .filter(exercise -> exercise.getDifficulty() == difficulty)
                .collect(Collectors.toList());
    }
    
    /**
     * 根据状态筛选习题
     * @param status 练习状态
     * @return 符合条件的习题列表
     */
    public List<Exercise> getExercisesByStatus(Exercise.Status status) {
        return exercises.stream()
                .filter(exercise -> exercise.getStatus() == status)
                .collect(Collectors.toList());
    }
    
    /**
     * 获取未开始的习题
     * @return 未开始的习题列表
     */
    public List<Exercise> getNotStartedExercises() {
        return getExercisesByStatus(Exercise.Status.NOT_STARTED);
    }
    
    /**
     * 获取已完成的习题
     * @return 已完成的习题列表
     */
    public List<Exercise> getCompletedExercises() {
        return getExercisesByStatus(Exercise.Status.COMPLETED);
    }
    
    /**
     * 获取进行中的习题
     * @return 进行中的习题列表
     */
    public List<Exercise> getInProgressExercises() {
        return getExercisesByStatus(Exercise.Status.IN_PROGRESS);
    }
    
    /**
     * 自动生成练习集（简单难度）
     * @param count 题目数量
     * @return 是否生成成功
     */
    public boolean generateSimpleExercises(int count) {
        Random random = new Random();
        boolean success = true;
        
        for (int i = 0; i < count; i++) {
            try {
                // 随机生成简单加法或减法
                boolean isAddition = random.nextBoolean();
                int num1, num2;
                
                if (isAddition) {
                    // 生成简单加法（结果不超过50）
                    num1 = random.nextInt(30) + 1;
                    num2 = random.nextInt(30) + 1;
                    if (num1 + num2 > 50) {
                        num2 = 50 - num1;
                    }
                    Expression expr = new AdditionExpression(num1, num2);
                    Exercise exercise = new Exercise(nextExerciseId++, expr, Exercise.Difficulty.EASY);
                    addExercise(exercise);
                } else {
                    // 生成简单减法（差不小于0，且数值较小）
                    num1 = random.nextInt(40) + 20;
                    num2 = random.nextInt(num1) + 1;
                    Expression expr = new SubtractionExpression(num1, num2);
                    Exercise exercise = new Exercise(nextExerciseId++, expr, Exercise.Difficulty.EASY);
                    addExercise(exercise);
                }
            } catch (Exception e) {
                success = false; // 某个题目生成失败
            }
        }
        
        return success;
    }
    
    /**
     * 自动生成练习集（中等难度）
     * @param count 题目数量
     * @return 是否生成成功
     */
    public boolean generateMediumExercises(int count) {
        Random random = new Random();
        boolean success = true;
        
        for (int i = 0; i < count; i++) {
            try {
                // 随机生成中等难度加法或减法
                boolean isAddition = random.nextBoolean();
                int num1, num2;
                
                if (isAddition) {
                    // 生成中等加法（结果在50-100之间）
                    num1 = random.nextInt(60) + 20;
                    num2 = random.nextInt(100 - num1) + 10;
                    if (num1 + num2 > 100) {
                        num2 = 100 - num1;
                    }
                    Expression expr = new AdditionExpression(num1, num2);
                    Exercise exercise = new Exercise(nextExerciseId++, expr, Exercise.Difficulty.MEDIUM);
                    addExercise(exercise);
                } else {
                    // 生成中等减法（较大数值，差不小于0）
                    num1 = random.nextInt(80) + 50;
                    num2 = random.nextInt(num1) + 20;
                    if (num1 - num2 < 0) {
                        num2 = num1;
                    }
                    Expression expr = new SubtractionExpression(num1, num2);
                    Exercise exercise = new Exercise(nextExerciseId++, expr, Exercise.Difficulty.MEDIUM);
                    addExercise(exercise);
                }
            } catch (Exception e) {
                success = false;
            }
        }
        
        return success;
    }
    
    /**
     * 生成混合难度练习集
     * @param easyCount 简单题目数量
     * @param mediumCount 中等题目数量
     * @param hardCount 困难题目数量
     * @return 是否生成成功
     */
    public boolean generateMixedExercises(int easyCount, int mediumCount, int hardCount) {
        boolean success = true;
        
        if (!generateSimpleExercises(easyCount)) {
            success = false;
        }
        
        if (!generateMediumExercises(mediumCount)) {
            success = false;
        }
        
        // 困难难度 - 较大数字或复杂组合
        Random random = new Random();
        for (int i = 0; i < hardCount; i++) {
            try {
                boolean isAddition = random.nextBoolean();
                int num1, num2;
                
                if (isAddition) {
                    // 生成接近100的加法
                    num1 = random.nextInt(90) + 10;
                    num2 = random.nextInt(100 - num1) + 1;
                    Expression expr = new AdditionExpression(num1, num2);
                    Exercise exercise = new Exercise(nextExerciseId++, expr, Exercise.Difficulty.HARD);
                    addExercise(exercise);
                } else {
                    // 生成需要多次尝试的减法
                    num1 = random.nextInt(95) + 5;
                    num2 = random.nextInt(num1) + 1;
                    Expression expr = new SubtractionExpression(num1, num2);
                    Exercise exercise = new Exercise(nextExerciseId++, expr, Exercise.Difficulty.HARD);
                    addExercise(exercise);
                }
            } catch (Exception e) {
                success = false;
            }
        }
        
        return success;
    }
    
    /**
     * 获取统计信息
     * @return 统计信息字符串
     */
    public String getStatistics() {
        StringBuilder sb = new StringBuilder();
        sb.append("=== 习题集统计信息 ===\n");
        sb.append("名称: ").append(setName).append("\n");
        sb.append("ID: ").append(setId).append("\n");
        sb.append("描述: ").append(description.isEmpty() ? "无" : description).append("\n");
        sb.append("创建时间: ").append(new java.util.Date(createTime)).append("\n");
        sb.append("总题目数: ").append(exercises.size()).append("\n");
        
        // 按难度统计
        Map<Exercise.Difficulty, Long> difficultyStats = exercises.stream()
                .collect(Collectors.groupingBy(Exercise::getDifficulty, Collectors.counting()));
        
        sb.append("\n--- 按难度分布 ---\n");
        for (Exercise.Difficulty diff : Exercise.Difficulty.values()) {
            long count = difficultyStats.getOrDefault(diff, 0L);
            sb.append(diff.getDisplayName()).append(": ").append(count).append(" 题\n");
        }
        
        // 按状态统计
        Map<Exercise.Status, Long> statusStats = exercises.stream()
                .collect(Collectors.groupingBy(Exercise::getStatus, Collectors.counting()));
        
        sb.append("\n--- 按状态分布 ---\n");
        for (Exercise.Status status : Exercise.Status.values()) {
            long count = statusStats.getOrDefault(status, 0L);
            sb.append(status.getDisplayName()).append(": ").append(count).append(" 题\n");
        }
        
        // 完成率统计
        int totalExercises = exercises.size();
        int completedExercises = getCompletedExercises().size();
        double completionRate = totalExercises > 0 ? (completedExercises * 100.0 / totalExercises) : 0.0;
        sb.append(String.format("\n完成率: %.1f%% (%d/%d)\n", completionRate, completedExercises, totalExercises));
        
        return sb.toString();
    }
    
    /**
     * 获取学习进度
     * @return 学习进度描述
     */
    public String getProgressSummary() {
        int total = exercises.size();
        int completed = getCompletedExercises().size();
        int notStarted = getNotStartedExercises().size();
        int inProgress = getInProgressExercises().size();
        
        StringBuilder sb = new StringBuilder();
        sb.append(String.format("[%s] 学习进度: %d/%d (%.1f%%)", 
                setName, completed, total, 
                total > 0 ? completed * 100.0 / total : 0));
        sb.append(String.format(" [未开始:%d, 进行中:%d, 已完成:%d]", 
                notStarted, inProgress, completed));
        
        return sb.toString();
    }
    
    /**
     * 显示习题集概览
     */
    public void showOverview() {
        System.out.println(getStatistics());
        
        // 显示几个示例题目
        if (!exercises.isEmpty()) {
            System.out.println("\n--- 题目预览 (前5题) ---");
            exercises.stream()
                    .limit(5)
                    .forEach(exercise -> System.out.println(exercise.getQuestion()));
        }
    }
    
    /**
     * 重写toString方法
     */
    @Override
    public String toString() {
        return String.format("习题集[%d]: %s (%d题)", setId, setName, exercises.size());
    }
    
    // Getter和Setter方法
    public String getSetName() {
        return setName;
    }
    
    public void setSetName(String setName) {
        this.setName = setName;
    }
    
    public int getSetId() {
        return setId;
    }
    
    public List<Exercise> getExercises() {
        return new ArrayList<>(exercises); // 返回副本，防止外部修改
    }
    
    public int getExerciseCount() {
        return exercises.size();
    }
    
    public long getCreateTime() {
        return createTime;
    }
    
    public String getDescription() {
        return description;
    }
    
    public void setDescription(String description) {
        this.description = description;
    }
    
    /**
     * 获取所有习题
     * @return 所有习题的列表
     */
    public List<Exercise> getAllExercises() {
        return new ArrayList<>(exercises); // 返回副本，防止外部修改
    }
    
    /**
     * 获取总习题数量
     * @return 总习题数量
     */
    public int getTotalExercises() {
        return exercises.size();
    }
    
    /**
     * 获取习题集名称
     * @return 习题集名称
     */
    public String getName() {
        return setName;
    }
    
    /**
     * 获取已完成的习题数量
     * @return 已完成习题数量
     */
    public int getCompletedCount() {
        return getCompletedExercises().size();
    }
    
    /**
     * 获取进行中的习题数量
     * @return 进行中习题数量
     */
    public int getInProgressCount() {
        return getInProgressExercises().size();
    }
    
    /**
     * 获取未开始的习题数量
     * @return 未开始习题数量
     */
    public int getNotStartedCount() {
        return getNotStartedExercises().size();
    }

    /**
     * 获取下一个可用的习题ID
     * @return 下一个习题ID
     */
    public int getNextExerciseId() {
        return nextExerciseId;
    }
}